/* 
 * A664p7_api.h -- API functions for the A664P7 over Ethernet library
 *
 */

#ifndef __INCLUDE_A664P7_API_H__
#define __INCLUDE_A664P7_API_H__

#include "protocol.h"
#include "pbuf.h"
#include "netif.h"
#include "LC_DataStructs.h"

#define A664P7_FAIL 0
#define A664P7_SUCC 1

#define A664P7_FALSE 0
#define A664P7_TRUE (!A664P7_FALSE)

/* VL mode flags */
#define VL_DISABLED 0
#define VL_TX_A    1		/* bit 1 -- Enable tx on network A */
#define VL_TX_B    2		/* bit 2 -- Enable tx on network B */
#define VL_TX_AB 3		    /* Both bits -- Enable tx on both networks */
#define VL_RX_A    4		/* bit 3 - Enable rx on net A */
#define VL_RX_B	   8		/* bit 4 - Enable rx on net B */
#define VL_RX_AB 12		    /* bits 3 and 4 - Enable rx on both networks */

/* More "failure" flags may be added in the future (the return value of functions
 *	returning A664P7_FAIL and A664P7_SUCC should be considered a bitfield).  Thusly,
 *	return values should be checked either using the IS_SUCCESS macro. */

#define IS_SUCCESS(A) ((A & A664P7_SUCC) > 0)

#define MOTOR_SUPPORT
#define CAN_SUPPORT
//#define LIGHT_SUPPORT

/* 
 * create_vl:
 *   Creates a fully populated VL and the associated PACKET. Destination MAC addresses are
 *   computed automatically.  The new VL is automatically added to the list of VLs managed by
 *   the tx/rx system.
 * INPUTS:  vl_num  -- VL_ID of the created VL
 *          vl_mode -- A value indicating the transmit/recieve mode for the vl
 *          na_dev  -- A pointer to the winpcap device to use for "Network A"
 *          nb_dev  -- A pointer to the winpcap device to use for "Network B"
 *          max_message_size  -- Maximum message size to be handled by the VL (fragmentation is not supported)
 *          src_mac -- A buffer containing the source mac address to be associated with the VL
 *          src_ip  -- An unsigned integer containing the source IP address to be associated with the VL
 *          dst_ip  -- An unsigned integer containing the destination IP address to be associated with the VL
 *          src_port-- An unsigned short integer containing the source port to be associated with the VL
 *          dst_port-- An unsigned short integer containing the destination port to be associated with the VL
 * RETURNS: A pointer to the newly created VL on success, NULL on failure
 */
VL *create_vl(int vl_num, int vl_mode, int max_message_size, 
				 unsigned char src_mac[6],
				 unsigned int src_ip, unsigned int dst_ip,
				 unsigned short int src_port, unsigned short int dst_port);
/* 
 * rx_all_vls:
 *  Reads through all messages in the recieve frame buffer and distributes them
 *  to VLs
 *  RETURNS: Number of Message->VL distributions to take place (includes all
 *           distributions, even those that have been overwritten by a newer
 *           frame read from the recieve frame buffer).
 */
int rx_all_vls(struct pbuf *p, struct netif *netif);

/* 
 * tx_vl: Transmits the packet assigned to "vl"
 * INPUTS: vl -- vl to transmit
 * RETURNS: Interfaces VL was transmitted on, using vl_mode flags
 */
int tx_vl(VL *vl);

/* 
 * tx_updated_vls: Transmits any VLs that have messages with messages that have been newly written but
 *                 not yet transmitted.
 */
void tx_updated_vls();

/* 
 * tx_all_vls: Transmits all txVLs
 */
void tx_all_vls();

/* 
 * read_vl_message: Copies the payload from the message assigned to "vl" to "buffer"
 * INPUTS: vl -- vl to read
 *         buffer -- Buffer to which payload will be copied
 *         buffer_size -- size of "buffer" in bytes
 * RETURNS: Size of copied data, in bytes (0 if no data was copied)
 */
int read_vl_message(VL *vl, char *buffer, int buffer_size);

/* 
 * write_vl_message: Copies the payload from the "buffer" to the message assigned to "vl"
 * INPUTS: vl -- vl to read
 *         buffer -- Buffer from which payload will be copied
 *         message_size -- size of the payload in bytes
 * RETURNS: 0 on failure, number of bytes written on success
 */
int write_vl_message(VL *vl, char *buffer, int message_size);

/* A664p7_auto_tx_mode: Generates TX mode flags to match available network
 *                    devices
 *  INPUTS:  net_a_dev -- A pointer to the network A dev, or NULL if Network A
 *                        is not used.
 *           net_b_dev -- A pointer to the network B dev, or NULL if Network B
 *                        is not used.
 *  RETURNS: A tx_mode value that can be used with create_vl
 */
int A664p7_auto_tx_mode();

/* A664p7_auto_rx_mode: Generates RX mode flags to match available network
 *                    devices
 *  INPUTS:  net_a_dev -- A pointer to the network A dev, or NULL if Network A
 *                        is not used.
 *           net_b_dev -- A pointer to the network B dev, or NULL if Network B
 *                        is not used.
 *  RETURNS: An rx_mode value that can be used with create_vl
 */
int A664p7_auto_rx_mode();

/* 
 * is_vl_message_new: Checks if a VLs payload is new 
 *					  (hasn't been transmitted (txVL) or hasn't been read (rxVL))
 * INPUTS: vl -- vl to check
 * RETURNS: 0 if the message is not new, 1 if the message is new
 */
int is_vl_message_new(VL *vl);
void initVl();
void vl_rx_event_process();
void vl_tx_event_process();
#ifdef MOTOR_SUPPORT
void vl_tx_event_process_motor();
#endif
#ifdef CAN_SUPPORT
void vl_tx_event_process_can();
void vl_tx_event_process_can_with_msg(CAN_DISCRETE_OUTPUT_RESPONSE_TYPE can_msg_out);
#endif

#endif
